﻿using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using System.Transactions;
using Microsoft.Practices.EnterpriseLibrary.Data;
using FriendsNearby.Services.Entities;
using InSTEDD.Labs.Geo;

namespace FriendsNearby.Services.Tests
{
    [TestFixture]
    public class LocationServiceFixture
    {
        TransactionScope testContextTransaction;
        LocationService locationService;
        Database database;

        [SetUp]
        public void SetUp()
        {
            testContextTransaction = new TransactionScope();

            database = DatabaseFactory.CreateDatabase("FriendsNearbyDB");

            // Temporaly clear DB
            database.ExecuteNonQuery(System.Data.CommandType.Text, "DELETE FROM UserLocation");
            database.ExecuteNonQuery(System.Data.CommandType.Text, "DELETE FROM UserLocationHistory");
            //
            FriendsNearbyFacade fnbFacade = new FriendsNearbyFacade();
            locationService = fnbFacade.LocationService as LocationService;
        }

        [TearDown]
        public void TearDown()
        {
            //testContextTransaction.Complete();
            testContextTransaction.Dispose();
        }

        [Test]
        public void NonRegisteredUserReturnsNullLocation()
        {
            UserInfo info = locationService.GetCurrentLocation("999999");
            Assert.AreEqual("999999", info.FacebookUserId);
            Assert.IsNull(info.Location);
        }

        [Test]
        public void StoredNewLocationCanBeRetrieved()
        {
            locationService.SetCurrentLocation("888", new LatLong(11.0f, -15.0f));
            UserInfo info = locationService.GetCurrentLocation("888");
            Assert.AreEqual("888", info.FacebookUserId);
            Assert.IsNotNull(info.Location);
            Assert.AreEqual(11.0f, info.Location.Lat);
            Assert.AreEqual(-15.0f, info.Location.Long);
        }

        [Test]
        public void LocationCanBeOverwritten()
        {
            locationService.SetCurrentLocation("777", new LatLong(2.0f, -2.0f));

            locationService.SetCurrentLocation("777", new LatLong(17.0f, -23.0f));
            UserInfo info = locationService.GetCurrentLocation("777");
            Assert.AreEqual("777", info.FacebookUserId);
            Assert.IsNotNull(info.Location);
            Assert.AreEqual(17.0f, info.Location.Lat);
            Assert.AreEqual(-23.0f, info.Location.Long);
        }


        [Test]
        public void LocationHistoryCanBeRetrievedAtSpecificPoint()
        {
            database.ExecuteNonQuery(System.Data.CommandType.Text,
                "INSERT INTO UserLocationHistory (FacebookUserID, Lat, Long, Timestamp) values (1, 10, 10, '2008-01-01')");
            database.ExecuteNonQuery(System.Data.CommandType.Text,
                "INSERT INTO UserLocationHistory (FacebookUserID, Lat, Long, Timestamp) values (1, 20, 20, '2008-02-02')");
            database.ExecuteNonQuery(System.Data.CommandType.Text,
                "INSERT INTO UserLocationHistory (FacebookUserID, Lat, Long, Timestamp) values (1, 30, 30, '2008-03-03')");
            database.ExecuteNonQuery(System.Data.CommandType.Text,
                "INSERT INTO UserLocationHistory (FacebookUserID, Lat, Long, Timestamp) values (1, 40, 40, '2008-04-04')");

            UserInfo info1 = locationService.GetLocationAt("1", DateTime.Parse("2008-01-01"));
            UserInfo info2 = locationService.GetLocationAt("1", DateTime.Parse("2008-02-02"));
            UserInfo info3 = locationService.GetLocationAt("1", DateTime.Parse("2008-03-03"));
            UserInfo info4 = locationService.GetLocationAt("1", DateTime.Parse("2008-04-04"));

            Assert.AreEqual(10, info1.Location.Lat);
            Assert.AreEqual(10, info1.Location.Long);
            Assert.AreEqual(20, info2.Location.Lat);
            Assert.AreEqual(20, info2.Location.Long);
            Assert.AreEqual(30, info3.Location.Lat);
            Assert.AreEqual(30, info3.Location.Long);
            Assert.AreEqual(40, info4.Location.Lat);
            Assert.AreEqual(40, info4.Location.Long);
        }
    }
}
